package com.zhangjunkai.net
{
	import com.hurlant.crypto.prng.ARC4;

	import flash.utils.ByteArray;

	public class TightMessageProcess
	{
		private var arc4:ARC4;
		private var key:ByteArray;

		/**
		 * 简短的消息加工类
		 * @param arc4key 如果使用arc4加密消息 则将key传入 否则消息将不加密
		 */
		public function TightMessageProcess(arc4key:ByteArray=null)
		{
			if (arc4key != null)
			{
				this.key=arc4key;
				arc4=new ARC4(arc4key);
			}

			//[Embed(source='/com/zhangjunkai/net/key', mimeType="application/octet-stream")]
			//private var keyfile:Class;
			//key=ByteArrayAsset(new keyfile());	
		}

		/**
		 * 编码
		 * @param arr 参数arr=[数据|数据|数据....]
		 * @return 完整的消息内容=[(0<=)包长度(<=255)|数据类型ID|数据|数据类型ID|数据|数据类型ID|数据...]
		 */
		public function encode(array:Array):ByteArray
		{
			var byteArray:ByteArray=new ByteArray();

			for each (var obj:Object in array)
			{
				if (obj is int)
				{
					var integer:int=obj as int;
					if (integer >= -128 && integer <= 127)
					{
						byteArray.writeByte(INT_8);
						byteArray.writeByte(integer);
					}
					else if (integer >= 0 && integer <= 255)
					{
						byteArray.writeByte(UINT_8);
						byteArray.writeByte(integer);
					}
					else if (integer >= -32768 && integer <= 32767)
					{
						byteArray.writeByte(INT_16);
						byteArray.writeShort(integer);
					}
					else if (integer >= 0 && integer <= 65535)
					{
						byteArray.writeByte(UINT_16);
						byteArray.writeShort(integer);
					}
					else if (integer >= -2147483648 && integer <= 2147483647)
					{
						byteArray.writeByte(INT_32);
						byteArray.writeInt(integer);
					}
					else if (integer >= 0 && integer <= 4294967295)
					{
						byteArray.writeByte(UINT_32);
						byteArray.writeUnsignedInt(integer);
					}
					else
					{
						throw new Error('不支持传输这个数字:' + integer);
					}
				}
				else if (obj is Boolean)
				{
					if (obj as Boolean)
					{
						byteArray.writeByte(BOOLEAN_TRUE);
					}
					else
					{
						byteArray.writeByte(BOOLEAN_FALSE);
					}
				}
				else if (obj is String)
				{
					byteArray.writeByte(STRING);
					byteArray.writeUTF(obj as String);
				}
				else
				{
					throw new Error('不支持传输这个类型的值:' + obj);
				}
			}

			var newbyteArray:ByteArray=new ByteArray();
			if (arc4 != null)
			{
				arc4.encrypt(byteArray);
				arc4.init(key);
			}
			newbyteArray.writeByte(byteArray.length);
			newbyteArray.writeBytes(byteArray);//, 0, byteArray.length);
			if (newbyteArray.length <= 255)
			{
				return newbyteArray;
			}
			else
			{
				throw new Error('生成后的消息长度为:' + newbyteArray.length + ' 这个消息长度不能超过255:' + array);
			}
			return null;
		}

		/**
		 * 解码
		 * @param byteArray 需要解码的byteArray不包括数据包前面的1位长度
		 * @return
		 */
		public function decode(byteArray:ByteArray):Array
		{
			var array:Array=new Array();
			if (arc4 != null)
			{
				arc4.decrypt(byteArray);
				arc4.init(key);
			}
			while (byteArray.bytesAvailable)
			{
				switch (byteArray.readUnsignedByte())
				{
					case INT_8:
						array.push(byteArray.readByte());
						break;
					case UINT_8:
						array.push(byteArray.readUnsignedByte());
						break;
					case INT_16:
						array.push(byteArray.readShort());
						break;
					case UINT_16:
						array.push(byteArray.readUnsignedShort());
						break;
					case INT_32:
						array.push(byteArray.readInt());
						break;
					case UINT_32:
						array.push(byteArray.readUnsignedInt());
						break;
					case BOOLEAN_TRUE:
						array.push(true);
						break;
					case BOOLEAN_FALSE:
						array.push(false);
						break;
					case STRING:
						array.push(byteArray.readUTF());
						break;
				}
			}
			return array;
		}

		/**
		 * 带符号 整数 -128 到 127
		 * @default
		 */
		private static const INT_8:int=1;
		/**
		 * 不带符号 0 到 255
		 * @default
		 */
		private static const UINT_8:int=2;
		/**
		 * 带符号 整数 -32768 到 32767
		 * @default
		 */
		private static const INT_16:int=3;
		/**
		 * 不带符号 0 到 65535
		 * @default
		 */
		private static const UINT_16:int=4;
		/**
		 * 带符号 整数 -2147483648 到 2147483647
		 * @default
		 */
		private static const INT_32:int=5;
		/**
		 * 不带符号 0 到 4294967295
		 * @default
		 */
		private static const UINT_32:int=6;
		/**
		 * 布尔值 true
		 * @default
		 */
		private static const BOOLEAN_TRUE:int=7;
		/**
		 * 布尔值 false
		 * @default
		 */
		private static const BOOLEAN_FALSE:int=8;
		/**
		 * UTF-8格式的字符串
		 * @default
		 */
		private static const STRING:int=9;
	}
}
